package com.kexio.file.service;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;

import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.kexio.file.entity.FileInfo;
import com.kexio.file.vo.FileInfoVO;

/**
 * 文件信息服务接口
 * 
 * 提供文件管理的核心业务逻辑，包括：
 * - 文件上传和下载
 * - 文件CRUD操作
 * - 文件查询和检索
 * - 文件统计和分析
 * - 多租户数据隔离
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
public interface FileInfoService {
    
    // ==================== 文件上传 ====================
    
    /**
     * 单文件上传
     * 
     * @param file 上传的文件
     * @param businessType 业务类型
     * @param businessKey 业务键（可选）
     * @param description 文件描述（可选）
     * @param isPublic 是否公开访问
     * @param expireTime 过期时间（可选）
     * @return 文件信息
     */
    FileInfo uploadFile(MultipartFile file, String businessType, String businessKey, 
                        String description, Boolean isPublic, LocalDateTime expireTime);
    
    /**
     * 流式文件上传
     * 
     * @param inputStream 文件流
     * @param originalName 原始文件名
     * @param contentType 内容类型
     * @param fileSize 文件大小
     * @param businessType 业务类型
     * @param businessKey 业务键（可选）
     * @param description 文件描述（可选）
     * @param isPublic 是否公开访问
     * @param expireTime 过期时间（可选）
     * @return 文件信息
     */
    FileInfo uploadFile(InputStream inputStream, String originalName, String contentType, 
                        Long fileSize, String businessType, String businessKey, 
                        String description, Boolean isPublic, LocalDateTime expireTime);
    
    /**
     * 批量文件上传
     * 
     * @param files 上传的文件列表
     * @param businessType 业务类型
     * @param businessKey 业务键（可选）
     * @param isPublic 是否公开访问
     * @return 文件信息列表
     */
    List<FileInfo> uploadFiles(List<MultipartFile> files, String businessType, 
                               String businessKey, Boolean isPublic);
    
    // ==================== 文件下载 ====================
    
    /**
     * 获取文件下载流
     * 
     * @param fileId 文件ID
     * @param updateAccessStats 是否更新访问统计
     * @return 文件输入流
     */
    InputStream downloadFile(String fileId, boolean updateAccessStats);
    
    /**
     * 获取文件预签名下载URL
     * 
     * @param fileId 文件ID
     * @param expireMinutes 有效期（分钟）
     * @return 预签名URL
     */
    String getPreSignedDownloadUrl(String fileId, int expireMinutes);
    
    // ==================== 基础CRUD操作 ====================
    
    /**
     * 根据ID查询文件信息
     * 
     * @param fileId 文件ID
     * @return 文件信息
     */
    FileInfo getById(String fileId);
    
    /**
     * 根据ID查询文件信息VO
     * 
     * @param fileId 文件ID
     * @return 文件信息VO
     */
    FileInfoVO getVOById(String fileId);
    
    /**
     * 更新文件信息
     * 
     * @param fileId 文件ID
     * @param fileInfo 更新的文件信息
     * @return 更新后的文件信息
     */
    FileInfo updateFileInfo(String fileId, FileInfo fileInfo);
    
    /**
     * 删除文件（逻辑删除）
     * 
     * @param fileId 文件ID
     * @return 是否删除成功
     */
    boolean deleteFile(String fileId);
    
    /**
     * 批量删除文件
     * 
     * @param fileIds 文件ID列表
     * @return 删除成功的数量
     */
    int batchDeleteFiles(List<String> fileIds);
    
    // ==================== 文件查询 ====================
    
    /**
     * 分页查询文件信息
     * 
     * @param current 当前页
     * @param size 每页大小
     * @param keyword 关键词（可选）
     * @param businessType 业务类型（可选）
     * @param uploaderId 上传者ID（可选）
     * @param status 状态（可选）
     * @return 分页结果
     */
    IPage<FileInfoVO> listFiles(long current, long size, String keyword, String businessType, 
                                String uploaderId, Integer status);
    
    /**
     * 根据业务键查询文件
     * 
     * @param businessKey 业务键
     * @return 文件信息列表
     */
    List<FileInfo> listByBusinessKey(String businessKey);
    
    /**
     * 根据业务类型查询文件
     * 
     * @param businessType 业务类型
     * @param current 当前页
     * @param size 每页大小
     * @return 分页结果
     */
    IPage<FileInfoVO> listByBusinessType(String businessType, long current, long size);
    
    /**
     * 根据上传者查询文件
     * 
     * @param uploaderId 上传者ID
     * @param current 当前页
     * @param size 每页大小
     * @return 分页结果
     */
    IPage<FileInfoVO> listByUploader(String uploaderId, long current, long size);
    
    /**
     * 根据文件类型查询文件
     * 
     * @param mimeTypePattern MIME类型模式（如 'image/%'）
     * @param current 当前页
     * @param size 每页大小
     * @return 分页结果
     */
    IPage<FileInfoVO> listByMimeType(String mimeTypePattern, long current, long size);
    
    // ==================== 文件统计 ====================
    
    /**
     * 统计用户文件数量
     * 
     * @param uploaderId 上传者ID
     * @return 文件数量
     */
    Long countByUploader(String uploaderId);
    
    /**
     * 统计用户文件总大小
     * 
     * @param uploaderId 上传者ID
     * @return 文件总大小（字节）
     */
    Long sumFileSizeByUploader(String uploaderId);
    
    /**
     * 统计业务类型文件数量
     * 
     * @param businessType 业务类型
     * @return 文件数量
     */
    Long countByBusinessType(String businessType);
    
    /**
     * 获取文件统计信息
     * 
     * @param uploaderId 上传者ID（可选，为空则统计全部）
     * @return 统计信息Map
     */
    java.util.Map<String, Object> getFileStats(String uploaderId);
    
    // ==================== 文件维护 ====================
    
    /**
     * 清理过期文件
     * 
     * @param batchSize 批次大小
     * @return 清理的文件数量
     */
    int cleanupExpiredFiles(int batchSize);
    
    /**
     * 清理长时间未访问的文件
     * 
     * @param days 天数
     * @param batchSize 批次大小
     * @return 清理的文件数量
     */
    int cleanupUnusedFiles(int days, int batchSize);
    
    /**
     * 更新文件访问统计
     * 
     * @param fileId 文件ID
     * @param incrementAccess 是否增加访问次数
     * @param incrementDownload 是否增加下载次数
     */
    void updateAccessStats(String fileId, boolean incrementAccess, boolean incrementDownload);
    
    /**
     * 批量更新文件状态
     * 
     * @param fileIds 文件ID列表
     * @param status 新状态
     * @return 更新的数量
     */
    int batchUpdateStatus(List<String> fileIds, Integer status);
    
    // ==================== 高级功能 ====================
    
    /**
     * 复制文件
     * 
     * @param sourceFileId 源文件ID
     * @param newBusinessType 新业务类型
     * @param newBusinessKey 新业务键（可选）
     * @param newDescription 新描述（可选）
     * @return 新文件信息
     */
    FileInfo copyFile(String sourceFileId, String newBusinessType, String newBusinessKey, String newDescription);
    
    /**
     * 重命名文件
     * 
     * @param fileId 文件ID
     * @param newDisplayName 新显示名称
     * @return 更新后的文件信息
     */
    FileInfo renameFile(String fileId, String newDisplayName);
    
    /**
     * 设置文件标签
     * 
     * @param fileId 文件ID
     * @param tags 标签（JSON格式）
     * @return 更新后的文件信息
     */
    FileInfo setFileTags(String fileId, String tags);
    
    /**
     * 检查文件是否存在重复（基于内容哈希）
     * 
     * @param contentMd5 MD5哈希值
     * @param contentSha256 SHA256哈希值（可选）
     * @return 重复的文件信息（如果存在）
     */
    FileInfo findDuplicateFile(String contentMd5, String contentSha256);
}
